package com.mingda.weathermagiccenter.utils.lzugis.geotools;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mingda.weathermagiccenter.utils.lzugis.geotools.utils.GeoUtils;
import com.mingda.weathermagiccenter.utils.lzugis.CommonMethod;
import com.mingda.weathermagiccenter.utils.lzugis.geotools.utils.GeoJSONUtil;
import com.mingda.weathermagiccenter.utils.lzugis.wContour.Contour;
import com.mingda.weathermagiccenter.utils.lzugis.wContour.Interpolate;
import com.mingda.weathermagiccenter.utils.lzugis.wContour.Global.Border;
import com.mingda.weathermagiccenter.utils.lzugis.wContour.Global.PointD;
import com.mingda.weathermagiccenter.utils.lzugis.wContour.Global.PolyLine;
import com.mingda.weathermagiccenter.utils.lzugis.wContour.Global.Polygon;

import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.TopologyException;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.geotools.data.DataUtilities;
import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.SchemaException;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geojson.feature.FeatureJSON;



import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.util.*;

/**
 * Created by admin on 2017/8/29.
 */
public class EquiSurface {
    private static String rootPath = System.getProperty("user.dir");

    /**
     * 生成等值面
     *
     * @param trainData    训练数据
     * @param dataInterval 数据间隔
     * @param size         大小，宽，高
     * @param boundryFile  四至
     * @param isclip       是否裁剪
     * @return
     */
    public String calEquiSurface(double[][] trainData,
                                 double[] dataInterval,
                                 int[] size,
                                 String boundryFile,
                                 JSONArray legend,
                                 boolean isclip,
                                 String wname) {
        String geojsonpogylon = "";
        try {
            double _undefData = -9999.0;
            SimpleFeatureCollection polygonCollection = null;
            List<PolyLine> cPolylineList = new ArrayList<PolyLine>();
            List<Polygon> cPolygonList = new ArrayList<Polygon>();

            int width = size[0],
                    height = size[1];
            double[] _X = new double[width];
            double[] _Y = new double[height];

            File file = new File(boundryFile);
            ShapefileDataStore shpDataStore = null;

            shpDataStore = new ShapefileDataStore(file.toURL());
            //设置编码
            Charset charset = Charset.forName("GBK");
            shpDataStore.setCharset(charset);
            String typeName = shpDataStore.getTypeNames()[0];
            SimpleFeatureSource featureSource = null;
            featureSource = shpDataStore.getFeatureSource(typeName);
            SimpleFeatureCollection fc = featureSource.getFeatures();

            double minX = fc.getBounds().getMinX();
            double minY = fc.getBounds().getMinY();
            double maxX = fc.getBounds().getMaxX();
            double maxY = fc.getBounds().getMaxY();

            Interpolate.CreateGridXY_Num(minX, minY, maxX, maxY, _X, _Y);
            double[][] _gridData = new double[width][height];

            int nc = dataInterval.length;

            _gridData = Interpolate.Interpolation_IDW_Neighbor(trainData,
                    _X, _Y, 12, _undefData);// IDW插值

            int[][] S1 = new int[_gridData.length][_gridData[0].length];
            /**
             * double[][] S0,
             * double[] X,
             * double[] Y,
             * int[][] S1,
             * double undefData
             */
            List<Border> _borders = Contour.tracingBorders(_gridData, _X, _Y,
                    S1, _undefData);

            /**
             * double[][] S0,
             * double[] X,
             * double[] Y,
             * int nc,
             * double[] contour,
             * double undefData,
             * List<Border> borders,
             * int[][] S1
             */
            cPolylineList = Contour.tracingContourLines(_gridData, _X, _Y, nc,
                    dataInterval, _undefData, _borders, S1);// 生成等值线

            cPolylineList = Contour.smoothLines(cPolylineList);// 平滑

            cPolygonList = Contour.tracingPolygons(_gridData, cPolylineList,
                    _borders, dataInterval);

            geojsonpogylon = getPolygonGeoJson(cPolygonList, legend, wname);

            if (isclip) {
                polygonCollection = GeoJSONUtil.readGeoJsonByString(geojsonpogylon);
               // FeatureSource dc = clipFeatureCollection(fc, polygonCollection);
               // geojsonpogylon = getPolygonGeoJson(dc.getFeatures());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return geojsonpogylon;
    }

    public String calEquiSurface_geojson(double[][] trainData,
                                 double[] dataInterval,
                                 int[] size,
                                 String geojson,
                                 JSONArray legend,
                                 boolean isclip,
                                 String wname) {
        String geojsonpogylon = "";
        try {
            double _undefData = -9999.0;
            SimpleFeatureCollection polygonCollection = null;
            List<PolyLine> cPolylineList = new ArrayList<PolyLine>();
            List<Polygon> cPolygonList = new ArrayList<Polygon>();

            int width = size[0],
                    height = size[1];
            double[] _X = new double[width];
            double[] _Y = new double[height];

            SimpleFeatureCollection fc = getSimpleFeatureCollection(geojson);
  
            double minX = fc.getBounds().getMinX()-1;
            double minY = fc.getBounds().getMinY()-1;
            double maxX = fc.getBounds().getMaxX()+1;
            double maxY = fc.getBounds().getMaxY()+1;

            Interpolate.CreateGridXY_Num(minX, minY, maxX, maxY, _X, _Y);
            double[][] _gridData = new double[width][height];

            dataInterval = getDataInterval(legend);
            int nc = dataInterval.length;

            _gridData = Interpolate.Interpolation_IDW_Neighbor(trainData,
                    _X, _Y, 12, _undefData);// IDW插值

            int[][] S1 = new int[_gridData.length][_gridData[0].length];
            /**
             * double[][] S0,
             * double[] X,
             * double[] Y,
             * int[][] S1,
             * double undefData
             */
            List<Border> _borders = Contour.tracingBorders(_gridData, _X, _Y,
                    S1, _undefData);

            /**
             * double[][] S0,
             * double[] X,
             * double[] Y,
             * int nc,
             * double[] contour,
             * double undefData,
             * List<Border> borders,
             * int[][] S1
             */
            cPolylineList = Contour.tracingContourLines(_gridData, _X, _Y, nc,
                    dataInterval, _undefData, _borders, S1);// 生成等值线

            cPolylineList = Contour.smoothLines(cPolylineList);// 平滑

            cPolygonList = Contour.tracingPolygons(_gridData, cPolylineList,
                    _borders, dataInterval);

            geojsonpogylon = getPolygonGeoJson(cPolygonList, legend, wname);

            if (isclip) {
                polygonCollection = GeoJSONUtil.readGeoJsonByString(geojsonpogylon);
               // FeatureSource dc = clipFeatureCollection(fc, polygonCollection);
               // geojsonpogylon = getPolygonGeoJson(dc.getFeatures());
                SimpleFeatureCollection sm = clipPolygonFeatureCollection(fc, polygonCollection);
                FeatureCollection featureCollection = sm;
                FeatureJSON featureJSON = new FeatureJSON();
                StringWriter writer = new StringWriter();
                featureJSON.writeFeatureCollection(featureCollection, writer);
                geojsonpogylon = writer.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return geojsonpogylon;
    }
    
    // public FeatureSource clipFeatureCollection(FeatureCollection fc,
    //                                            SimpleFeatureCollection gs) {
    //     FeatureSource cs = null;
    //     try {
    //         List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
    //         FeatureIterator contourFeatureIterator = gs.features();
    //         FeatureIterator dataFeatureIterator = fc.features();
    //         while (dataFeatureIterator.hasNext()) {
    //             Feature dataFeature = dataFeatureIterator.next();
    //             Geometry dataGeometry = (Geometry) dataFeature.getProperty(
    //                     "the_geom").getValue();
    //             while (contourFeatureIterator.hasNext()) {
    //                 Feature contourFeature = contourFeatureIterator.next();
    //                 Geometry contourGeometry = (Geometry) contourFeature
    //                         .getProperty("geometry").getValue();
    //                 double lv = (Double) contourFeature.getProperty("lvalue")
    //                         .getValue();
    //                 double hv = (Double) contourFeature.getProperty("hvalue")
    //                         .getValue();
    //                 if (dataGeometry.intersects(contourGeometry)) {
    //                     Geometry geo = dataGeometry
    //                             .intersection(contourGeometry);
    //                     Map<String, Object> map = new HashMap<String, Object>();
    //                     map.put("the_geom", geo);
    //                     map.put("lvalue", lv);
    //                     map.put("hvalue", hv);
    //                     values.add(map);
    //                 }

    //             }

    //         }

    //         contourFeatureIterator.close();
    //         dataFeatureIterator.close();

    //         SimpleFeatureCollection sc = FeaureUtil
    //                 .creatSimpleFeatureByFeilds(
    //                         "polygons",
    //                         "crs:4326,the_geom:MultiPolygon,lvalue:double,hvalue:double",
    //                         values);
    //         cs = FeaureUtil.creatFeatureSourceByCollection(sc);

    //     } catch (Exception e) {
    //         e.printStackTrace();
    //         return cs;
    //     }

    //     return cs;
    // }

    

    // public String getPolygonGeoJson(FeatureCollection fc) {
    //     FeatureJSON fjson = new FeatureJSON();
    //     StringBuffer sb = new StringBuffer();
    //     try {
    //         sb.append("{\"type\": \"FeatureCollection\",\"features\": ");
    //         FeatureIterator itertor = fc.features();
    //         List<String> list = new ArrayList<String>();
    //         while (itertor.hasNext()) {
    //             SimpleFeature feature = (SimpleFeature) itertor.next();
    //             StringWriter writer = new StringWriter();
    //             fjson.writeFeature(feature, writer);
    //             list.add(writer.toString());
    //         }
    //         itertor.close();
    //         sb.append(list.toString());
    //         sb.append("}");
    //     } catch (Exception e) {
    //         e.printStackTrace();
    //     }
    //     return sb.toString();
    // }

    // private SimpleFeatureCollection clipPolygonFeatureCollection(FeatureCollection fc,
    //                                                              SimpleFeatureCollection gs) throws SchemaException, IOException {
    //     SimpleFeatureCollection simpleFeatureCollection = null;
    //     SimpleFeatureType TYPE = DataUtilities.createType("polygons",
    //             "the_geom:MultiPolygon,lvalue:double,hvalue:double,fcolor:string");
    //     List<SimpleFeature> list = new ArrayList<>();
    //     SimpleFeatureIterator contourFeatureIterator = gs.features();
    //     FeatureIterator dataFeatureIterator = fc.features();
    //     while (dataFeatureIterator.hasNext()){
    //         SimpleFeature dataFeature = (SimpleFeature) dataFeatureIterator.next();
    //         Geometry dataGeometry = (Geometry) dataFeature.getDefaultGeometry();
    //         contourFeatureIterator = gs.features();
    //         while (contourFeatureIterator.hasNext()){
    //             SimpleFeature contourFeature = contourFeatureIterator.next();
    //             Geometry contourGeometry = (Geometry) contourFeature.getDefaultGeometry();
    //             Double lv = (Double) contourFeature.getProperty("lvalue").getValue();
    //             Double hv = (Double) contourFeature.getProperty("hvalue").getValue();
    //             String fcolor = (String) contourFeature.getProperty("fcolor").getValue();;
    //             if (dataGeometry.getGeometryType() == "MultiPolygon"){
    //                 for (int i = 0; i <dataGeometry.getNumGeometries(); i++){
    //                     Geometry geom = dataGeometry.getGeometryN(i);
    //                     if (geom.intersects(contourGeometry)){
    //                         Geometry geo = geom.intersection(contourGeometry);
    //                         SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
    //                         featureBuilder.add(geo);
    //                         featureBuilder.add(lv);
    //                         featureBuilder.add(hv);
    //                         featureBuilder.add(fcolor);
    //                         SimpleFeature feature = featureBuilder.buildFeature(null);
    //                         list.add(feature);
 
    //                     }
    //                 }
 
    //             } else {
    //                 if (dataGeometry.intersects(contourGeometry)){
    //                     Geometry geo = dataGeometry.intersection(contourGeometry);
    //                     SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
    //                     featureBuilder.add(geo);
    //                     featureBuilder.add(lv);
    //                     featureBuilder.add(hv);
    //                     featureBuilder.add(fcolor);
    //                     SimpleFeature feature = featureBuilder.buildFeature(null);
    //                     list.add(feature);
 
    //                 }
 
    //             }
 
    //         }
    //     }
 
    //     contourFeatureIterator.close();
    //     dataFeatureIterator.close();
    //     simpleFeatureCollection = new ListFeatureCollection(TYPE, list);
 
    //     return simpleFeatureCollection;
 
    // }

    private SimpleFeatureCollection clipPolygonFeatureCollection(FeatureCollection fc,
                                                            SimpleFeatureCollection gs) throws SchemaException, IOException {
        SimpleFeatureCollection simpleFeatureCollection;
        SimpleFeatureType TYPE = DataUtilities.createType("polygons",
                "the_geom:MultiPolygon,lvalue:double,hvalue:double,fcolor:string");
        List<SimpleFeature> list = new ArrayList<>();
        
        // 使用try-with-resources确保迭代器关闭
        try (FeatureIterator<SimpleFeature> dataFeatureIterator = fc.features()) {
            while (dataFeatureIterator.hasNext()) {
                SimpleFeature dataFeature = dataFeatureIterator.next();
                Geometry dataGeometry = (Geometry) dataFeature.getDefaultGeometry();
                
                // 清理原始几何图形（修复潜在拓扑问题）
                Geometry cleanedDataGeom = GeometryCleaner.clean(dataGeometry);
                
                try (SimpleFeatureIterator contourFeatureIterator = gs.features()) {
                    while (contourFeatureIterator.hasNext()) {
                        SimpleFeature contourFeature = contourFeatureIterator.next();
                        Geometry contourGeometry = (Geometry) contourFeature.getDefaultGeometry();
                        
                        // 清理裁剪几何图形
                        Geometry cleanedContourGeom = GeometryCleaner.clean(contourGeometry);
                        
                        Double lv = (Double) contourFeature.getProperty("lvalue").getValue();
                        Double hv = (Double) contourFeature.getProperty("hvalue").getValue();
                        String fcolor = (String) contourFeature.getProperty("fcolor").getValue();
                        
                        // 使用缓冲容差处理边界问题
                        Geometry bufferedContour = cleanedContourGeom.buffer(1e-8);
                        
                        if (cleanedDataGeom.getGeometryType().equals("MultiPolygon")) {
                            for (int i = 0; i < cleanedDataGeom.getNumGeometries(); i++) {
                                processGeometry(
                                        cleanedDataGeom.getGeometryN(i),
                                        bufferedContour,
                                        lv, hv, fcolor,
                                        TYPE,
                                        list
                                );
                            }
                        } else {
                            processGeometry(
                                    cleanedDataGeom,
                                    bufferedContour,
                                    lv, hv, fcolor,
                                    TYPE,
                                    list
                            );
                        }
                    }
                }
            }
        }
        
        simpleFeatureCollection = new ListFeatureCollection(TYPE, list);
        return simpleFeatureCollection;
    }

    // 辅助方法：处理几何相交操作
    private void processGeometry(Geometry geom, 
                                Geometry contour,
                                Double lv, Double hv, String fcolor,
                                SimpleFeatureType type,
                                List<SimpleFeature> resultList) {
        if (geom.intersects(contour)) {
            SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(type);
            try {
                // 使用带容差的相交操作
                Geometry intersection = geom.intersection(contour);
                
                // 跳过空结果
                if (intersection.isEmpty() || !intersection.isValid()) {
                    return;
                }
                
                // 确保结果类型为多边形
                try {
                    intersection = intersection.buffer(0); // 尝试修复几何
                } catch (TopologyException e) {
                    intersection = intersection.buffer(1e-10); // 使用微小缓冲容差重试
                }
                
                // 创建特征
                
                featureBuilder.add(intersection);
                featureBuilder.add(lv);
                featureBuilder.add(hv);
                featureBuilder.add(fcolor);
                resultList.add(featureBuilder.buildFeature(null));
                
            } catch (TopologyException e) {
                // 异常处理：使用缓冲容差重试
                Geometry safeIntersection = geom.buffer(1e-10).intersection(contour.buffer(1e-10));
                if (!safeIntersection.isEmpty()) {
                    featureBuilder.add(safeIntersection);
                    featureBuilder.add(lv);
                    featureBuilder.add(hv);
                    featureBuilder.add(fcolor);
                    resultList.add(featureBuilder.buildFeature(null));
                }
            }
        }
    }

    // 几何清理工具类
    static class GeometryCleaner {
        private static final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory();
        private static final double PRECISION_SCALE = 1e10;  // 10位小数精度
        
        public static Geometry clean(Geometry geometry) {
            // 按精度缩放坐标->舍入->缩放回原始精度
            Coordinate[] coords = geometry.getCoordinates();
            for (Coordinate coord : coords) {
                coord.x = Math.round(coord.x * PRECISION_SCALE) / PRECISION_SCALE;
                coord.y = Math.round(coord.y * PRECISION_SCALE) / PRECISION_SCALE;
            }
            return GEOMETRY_FACTORY.createGeometry(geometry);
        }
    }


    public String getPolygonGeoJson(List<Polygon> cPolygonList, JSONArray legend, String wname) {
        String geo = null;
        String geometry = " { \"type\":\"Feature\",\"geometry\":";
        String properties = ",\"properties\":{ \"hvalue\":";

        String head = "{\"type\": \"FeatureCollection\"," + "\"features\": [";
        String end = "  ] }";
        if (cPolygonList == null || cPolygonList.size() == 0) {
            return null;
        }
        try {
            for (Polygon pPolygon : cPolygonList) {

                List<Object> ptsTotal = new ArrayList<Object>();
                List<Object> pts = new ArrayList<Object>();

                PolyLine pline = pPolygon.OutLine;

                for (PointD ptD : pline.PointList) {
                    List<Double> pt = new ArrayList<Double>();
                    pt.add(ptD.X);
                    pt.add(ptD.Y);
                    pts.add(pt);
                }

                ptsTotal.add(pts);

                if (pPolygon.HasHoles()) {
                    for (PolyLine cptLine : pPolygon.HoleLines) {
                        List<Object> cpts = new ArrayList<Object>();
                        for (PointD ccptD : cptLine.PointList) {
                            List<Double> pt = new ArrayList<Double>();
                            pt.add(ccptD.X);
                            pt.add(ccptD.Y);
                            cpts.add(pt);
                        }
                        if (cpts.size() > 0) {
                            ptsTotal.add(cpts);
                        }
                    }
                }

                JSONObject js = new JSONObject();
                js.put("type", "Polygon");
                js.put("coordinates", ptsTotal);
                double hv = pPolygon.HighValue;
                double lv = pPolygon.LowValue;
               
                if (hv == lv) {
                    if (pPolygon.IsClockWise) {
                        if (!pPolygon.IsHighCenter) {
                            hv = hv - 0.1;
                            lv = lv - 0.1;
                        }

                    } else {
                        if (!pPolygon.IsHighCenter) {
                            hv = hv - 0.1;
                            lv = lv - 0.1;
                        }
                    }

                } else {
                    if (!pPolygon.IsClockWise) {
                        lv = lv + 0.1;
                    } else {
                        if (pPolygon.IsHighCenter) {
                            hv = hv - 0.1;
                        }
                    }
                }
                //通过lv获取颜色
                String fcolor = getColors(legend, String.valueOf(lv));

                geo = geometry + js.toString() + properties + hv
                        + ", \"lvalue\":" + lv 
                        + ", \"fcolor\":\"" + fcolor 
                        //+ ", \"wname\":\"" + wname 
                        + "\"} }" + "," + geo;

            }
            if (geo.contains(",")) {
                geo = geo.substring(0, geo.lastIndexOf(","));
            }

            geo = head + geo + end;
        } catch (Exception e) {
            e.printStackTrace();
            return geo;
        }
        return geo;
    }

    // public static String getColors(JSONArray legend, String val){
    //     String color = "";
    //     for (Object obj : legend) {
    //         JSONObject entry = (JSONObject) obj;
    //         if (entry.containsKey("value") && entry.containsKey("color")) {
    //             // 可根据 value 匹配 val 获取对应 color
    //             if (val.equals(entry.getString("value"))) {
    //                 color = entry.getString("color");
    //                 break;
    //             }
    //         }
    //     }
    //     return color;
    // }

     public static String getColors(JSONArray legend, String val) {
        String exactMatchColor = ""; // 精确匹配的颜色
        String lessMatchColor = "";  // 小于val的最大值对应的颜色
        Double maxLessValue = Double.NEGATIVE_INFINITY; // 记录小于val的最大数值

        for (Object obj : legend) {
            JSONObject entry = (JSONObject) obj;
            if (entry.containsKey("value") && entry.containsKey("color")) {
                String entryValue = entry.getString("value");
                String entryColor = entry.getString("color");

                // 1. 精确匹配：直接返回对应颜色
                if (val.equals(entryValue) || Double.parseDouble(val)==Double.parseDouble(entryValue)) {
                    exactMatchColor = entryColor;
                    break; // 找到精确匹配后立即终止循环
                }

                // 2. 处理数值型范围匹配（仅当val和entryValue均为数值时生效）
                try {
                    double numVal = Double.parseDouble(val);
                    double numEntry = Double.parseDouble(entryValue);
                    
                    if (numEntry < numVal && numEntry > maxLessValue) {
                        maxLessValue = numEntry;
                        lessMatchColor = entryColor;
                    }
                } catch (NumberFormatException e) {
                    // 非数值类型，跳过数值比较
                }
            }
        }

        // 优先返回精确匹配，否则返回范围匹配结果
        return !exactMatchColor.isEmpty() ? exactMatchColor : lessMatchColor;
    }

    public static double[] getDataInterval(JSONArray legend){
        double[] dataInterval = new double[legend.size()];
        for (int i = 0; i < legend.size(); i++) {
            JSONObject entry = legend.getJSONObject(i);
            if (entry.containsKey("value")) {
                dataInterval[i] = entry.getDouble("value");
            }
        }
        return dataInterval;
    }

    public static DefaultFeatureCollection getSimpleFeatureCollection(String geojson) { 
        DefaultFeatureCollection collection = new DefaultFeatureCollection();
        try {
            Geometry geometries = GeoUtils.geojson2Geometry(geojson);
            // 1.定义 SimpleFeatureType
            SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
            typeBuilder.setName("CityPoints");
            typeBuilder.add("geometry", MultiPolygon.class); // 指定为点类型
            typeBuilder.add("name", String.class);
            SimpleFeatureType featureType = typeBuilder.buildFeatureType();

            // 2. 创建 FeatureBuilder 和集合
            SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
           

            // 3. 遍历 Geometry 列表，逐个创建 Feature
            featureBuilder.set("geometry", geometries);
            featureBuilder.set("name", "边界");
            SimpleFeature feature = featureBuilder.buildFeature("bianjie");
            collection.add(feature);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return collection;
    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();

        EquiSurface equiSurface = new EquiSurface();
        CommonMethod cm = new CommonMethod();

        double[] bounds = {73.4510046356223, 18.1632471876417,
                134.976797646506, 53.5319431522236};

        double[][] trainData = new double[3][100];

        for (int i = 0; i < 100; i++) {
            double x = bounds[0] + new Random().nextDouble() * (bounds[2] - bounds[0]),
                    y = bounds[1] + new Random().nextDouble() * (bounds[3] - bounds[1]),
                    v = 0 + new Random().nextDouble() * (45 - 0);
            trainData[0][i] = x;
            trainData[1][i] = y;
            trainData[2][i] = v;
        }

        double[] dataInterval = new double[]{20, 25, 30, 35, 40, 45};

        String boundryFile = rootPath + "/data/shp/bou1_4p.shp";

        int[] size = new int[]{100, 100};

        boolean isclip = true;

        try {
            //String strJson = equiSurface.calEquiSurface(trainData, dataInterval, size, boundryFile, isclip);
            //String strFile = rootPath + "/out/china1.json";
            //cm.append2File(strFile, strJson);
            //System.out.println(strFile + "差值成功, 共耗时" + (System.currentTimeMillis() - start) + "ms");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
